﻿#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

//*** 操作符分类：
//1.算术操作符
//2.移位操作符
//3.位操作符
//4.赋值操作符
//5.单目操作符
//6.关系操作符
//7.逻辑操作符
//8.条件操作符
//9.逗号表达式
//10.下标引用、函数调用和结构成员


//*************************************************
//1.算数操作符（+ - * / %）

//1. 除了 % 操作符之外，其他的几个操作符可以作用于整数和浮点数。
//2. % 操作符的两个操作数必须为整数。返回的是整除之后的余数
//3. 对于 / 操作符如果两个操作数都为整数，执行整数除法。
//   而只要有浮点数执行的就是浮点数除法。


//****************************************************
//2.移位操作符（>>  <<）
//（移动的是二进制的位）(移位操作符的操作数只能是整数)

//1.左移操作符（ << ）
// 左边丢弃，右边补0（使用补码）
//   （补充：整数在内存中存储的都是补码的二进制序列）

//int main()
//{
//	int m = 7;
//	int n = m << 1;
//	printf("m=%d n=%d", m, n);//打印的是原码
//	return 0;
//}
//
//若m的值在没被赋值的情况下，自身的值不会改变
//7的原码（反码、补码）是：
//00000000 00000000 00000000 00000111（正整数的原码，反码，补码相同）
//左移一位后
//00000000 00000000 00000000 00001110 = 14

//int main()
//{
//	int m = -7;
//	int n = m << 1;
//	printf("m=%d n=%d", m, n);//打印的是原码
//	return 0;
//}

//-7的原码是：
//10000000 00000000 00000000 00000111
//11111111 11111111 11111111 11111000（反码）（符号位不会取反）
//11111111 11111111 11111111 11111001（补码）
//左移一位后
//11111111 11111111 11111111 11110010（补码）
//10000000 00000000 00000000 00001110（n的原码）= -14


//2.右移操作符( >> )   -逻辑移位：左边用0填充，右边丢弃
//                     -算术移位：左边用原该值的符号位填充，右边丢弃
//                       （大多数编译器默认）

//int main()
//{
//	int m = -7;
//	int n = m >> 1;//右移一位
//	printf("m=%d n=%d", m, n);//打印的是原码
//	return 0;
//}

//警告⚠：
//对于移位运算符，不要移动负数位，这个是标准未定义的。


//*****************************************
//3.位操作符（& | ^）


//1.
//&  按（二进制）位与
//&：两个整数的相同位置：都为1时，&在该位置为1
//                       都为0时，&在该位置为0
//                       一个为0，一个为1时，&在该位置为0
//int main()
//{
//	int a = 3;
//	int b = -5;
//	int c = a & b;
//	printf("%d ", c);
//	return 0;
//}
//00000000 00000000 00000000 00000011  --  3的原码
//10000000 00000000 00000000 00000101  -- -5的原码
//11111111 11111111 11111111 11111011  -- -5的补码
//00000000 00000000 00000000 00000011  --  3的补码
//00000000 00000000 00000000 00000011 = 3  --  3 & -5


//&1和<<、>>一起使用可以知道一个整数补码的二进制序列的任何一位
//int main()
//{
//	int a = 3;
//	int c = (a >> 2) & 1;
//	printf("c=%d", c);
//	return 0;
//}
//00000000 00000000 00000000 00000011  --  3的补码
//00000000 00000000 00000000 00000001  --  1的补码
//想知道3的补码的最后一位是什么
//00000000 00000000 00000000 00000001  --  3 & 1  //为1
//想知道3的补码的倒数第二位是什么
//(3>>1)&1
//00000000 00000000 00000000 00000001  --  3>>1的补码
//00000000 00000000 00000000 00000001  --  1的补码
//00000000 00000000 00000000 00000001  --  (3>>1) & 1  //为1


//2.
// |(按位或)
//int main()
//{
//	int a = 3;
//	int b = -5;
//	int c = a | b;
//	printf("c=%d", c);
//	return 0;
//}
//c=-5

//00000000 00000000 00000000 00000011  --  3的原码
//10000000 00000000 00000000 00000101  -- -5的原码
//11111111 11111111 11111111 11111011  -- -5的补码
//00000000 00000000 00000000 00000011  --  3的补码
//11111111 11111111 11111111 11111011  --  3 | -5的补码
//10000000 00000000 00000000 00000101 = -5 --  3 | -5的原码


//3.
// ^(相同为0，相异为1)
//int main()
//{
//	int a = 3;
//	int b = -5;
//	int c = a ^ b;
//	printf("c=%d", c);
//	return 0;
//}
//c=-8

//00000000 00000000 00000000 00000011  --  3的原码
//10000000 00000000 00000000 00000101  -- -5的原码
//11111111 11111111 11111111 11111011  -- -5的补码
//00000000 00000000 00000000 00000011  --  3的补码
//11111111 11111111 11111111 11111000  --  3 ^ -5的补码
//10000000 00000000 00000000 00001000 = -8 --  3 ^ -5的原码

//int main()
//{
//	int a = 3;
//	int b = -5;
//	int c = a ^ b ^ a;
//	printf("c=%d ", c);
//	return 0;
//}
//c=-5

//一般方法
//00000000 00000000 00000000 00000011  --  3的原码
//10000000 00000000 00000000 00000101  -- -5的原码
//11111111 11111111 11111111 11111011  -- -5的补码
//00000000 00000000 00000000 00000011  --  3的补码
//11111111 11111111 11111111 11111000  --  3 ^ -5的补码
//00000000 00000000 00000000 00000011  --  3的补码
//11111111 11111111 11111111 11111011  --  3 ^ -5 ^ 3的补码
//10000000 00000000 00000000 00000101 = -5 --  3 ^ -5 ^ 3的原码

//交换律
//a ^ b ^ a = a ^ a ^ b = 0 ^ b = b = -5

//int main()
//{
//	int a = 10;
//	int b = 20;
//	a = a ^ b;
//	b = a ^ b;
//	a = a ^ b;
//	printf("a = %d b = %d\n", a, b);
//	return 0;
//}



//*******************************************************
//4.赋值操作符

//int main()
//{
//	int a = 1;//不是赋值，是初始化
//	a = 20;//赋值
//	return 0;
//}


//int main()
//{
//	int a = 1;
//	int x = 0;
//	int y = 2;
//	a = x = y + 1;//连续赋值
//	return 0;
//}

//int main()
//{
//	int a = 1;
//	int x = 0;
//	int y = 2;
//	x = y + 1;
//	a = x;
//	这样的写法是不是更加清晰爽朗而且易于调试。
//	return 0;
//}


//int main()
//{
//	int x = 9;
//	x = x + 2;
//	x += 2;//复合赋值
//	//两种方式是一个意思
//	//其他运算符一样的道理。这样写更加简洁、高效
//	return 0;
//}


//******************************************
//5.单目操作符
//int main()
//{
//	int a = 5;
//	int b = !a;
//	printf("b=%d", b);
//	return 0;
//}
////b=0


//int main()
//{
//	int a = 10;
//	int* p = &a;//a变量的地址
//
//	int arr[10];
//	int(*pa)[10] = &arr;//这是数组的地址
//	return 0;
//}

//
//int main()
//{
//	int a = 10;
//	int* p = &a;//a变量的地址
//	printf("*p=%d", *p);
//	//对p进行解引用操作，*p是通过p中存放的地址，找到p指向的对象
//	//*p其实就是a
//	return 0;
//}
////*p=10


//int main()
//{
//	int a = 10;
//	printf("%d", sizeof a );//4
//	printf("%zd", sizeof(int));//4
//	return 0;
//}


//int main()
//{
//	int a = 0;
//	printf("~a=%d\n", ~a);
//	return 0;
//}
//~a=-1

//00000000 00000000 00000000 00000000  -- 0的补码
//11111111 11111111 11111111 11111111  -- ~a的补码（符号位也取反）
//10000000 00000000 00000000 00000001 = -1 -- ~a的原码


//int main()
//{
//	int a = 10;
//	//00000000 00000000 00000000 00001010
//	//如何让10的补码的二进制序列的倒数第五位从0变成1，其它位不变
//	// 让10 | (1<<4)
//	//00000000 00000000 00000000 00010000  -- 1<<4 的补码
//	//00000000 00000000 00000000 00011010
//	a |= (1 << 4);
//	printf("a=%d\n", a);//a=26
//	//如何再让a的补码的二进制序列的倒数第五位从1变成0，其它位不变
//	//00000000 00000000 00000000 00011010
//	//让 a & 下面的数
//	//11111111 11111111 11111111 11101111（可以看出这是 ~（1<<4） ）
//	//00000000 00000000 00000000 00001010
//	a &= (~(1 << 4));
//	printf("a=%d\n", a);//a=10
//	return 0;
//}
//


//int main()
//{
//	int a = 3;
//	int b = 5;
//	int c = ++a;
//	int d = b++;
//	printf("a=%d c=%d", a, c);//a=4 c=4
//	printf("b=%d d=%d", b, d);//b=6 d=5
//	return 0;
//}

//int main()
//{
//	int a = 1;
//	int b = (++a) + (++a) + (++a);
//	printf("b=%d", b);
//	return 0;
//}
//

//int main()
//{
//	int a = 3.14;
//	//3.14 会被编译器识别为double类型
//	return 0;
//}

//int main()
//{
//	int i = 0, a = 0, b = 2, c = 3, d = 4;
//	i = a++||++b||d++;
//	printf("a = %d\n b = %d\n c = %d\nd = %d\n %d", a, b, c, d,i);
//	return 0;
//}



//***************************************************
//条件操作符

//int main()
//{
//	int a = 10;
//	int b = 8;
//	int max;
//	//if (a > b)
//	//	max = a;
//	//else
//	//	max = b;
//	max = (a > b ? a : b);//上面注释行可简写为该条件表达式
//	printf("%d\n", max);
//	return 0;
//}


//int main()
//{
//	int a = 1;
//	int b = 2;
//	int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式
//	printf("%d\n", c);
//	return 0;
//}

//int main()
//{
//	int v1, v2, v3, v4, v5, v6;
//	fun((v1, v2), (v3, v4), v5, v6);
//	return 0;
//}



//************************************************
//下标引用操作符

//int main()
//{
//	int arr[10] = { 0 };
//	int arr[3] = 4;//[]里面的值叫做索引值
//	return 0;
//}


//int main()
//{
//	test1(); //实用（）作为函数调用操作符。
//	test2("hello bit.");//实用（）作为函数调用操作符。
//	return 0;
//}



//struct card
//{
//	char name[20];
//	int age;
//};
//
//void Print(struct card* pa)
//{
//	printf("%s %d\n", pa->name, pa->age);
//}
//
//int main()
//{
//	struct card a = { "zhangsan",18 };
//	printf("%s %d\n", a.name, a.age);
//
//	Print(&a);
//	return 0;
//}



//int main()
//{
//	char a = 5;
//	//00000101
//	char b = 126;
//	//01111110
//	char c = a + b;//a和b要进行算术运算，且都为char类型，因此要进行整型提升
//
//	//a、b的符号位（即最高位）都为0，所以用0提升
//	//00000000 00000000 00000000 00000101  -- a整型提升后
//	//00000000 00000000 00000000 01111110  -- b整型提升后
//	//00000000 00000000 00000000 10000011  -- a+b
//	//10000011  -- c时char类型，所以只能放8个比特位
//
//	printf("c=%d\n", c);
//	//c要以%d形式打印，又是char类型，就要整型提升
//	//c的符号位是1，所以用1提升
//	//11111111 11111111 11111111 10000011  -- c整型提升后（补码）
//	//10000000 00000000 00000000 01111101 = -125 -- c整型提升后（原码）
//
//	return 0;
//}
////c=-125


//int main()
//{
//	char a = 0xb6;//1011 0110
//	short b = 0xb600;//1011 0110 0000 0000
//	int c = 0xb6000000;
//	if (a == 0xb6)
//		printf("a");
//	if (b == 0xb600)
//		printf("b");
//	if (c == 0xb6000000)
//		printf("c");
//	return 0;
//}
////c

//int main()
//{
//	char c = 1;
//	printf("%u\n", sizeof(c));
//	printf("%u\n", sizeof(+c));
//	printf("%u\n", sizeof(-c));
//	return 0;
//}


//交换两个变量（不创建临时变量）
//int main()
//{
//	int a = 10;
//	int b = 20;
//	a = a ^ b; 
//	b = a ^ b;//b=a^b^b=a^0=a
//	a = a ^ b;//a=a^b^a=b^0=b
//	printf("%d %d", a, b);
//	return 0;
//}


//统计二进制中1的个数
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int i = 0;
//	int count = 0;
//	/*for (i = 1; i <= 32; i++)
//	{
//		//2.
//		if ((n & 1) == 1)
//			count++;
//		n >>= 1;
//
//		//3.
//		if (((n >> i) & 1) == 1)
//			count++;
//	}*/
//	//4（更为精妙）
//	while(n)
//	{
//		n = n & (n - 1);
//		count++;
//	}
//	printf("%d", count);
//	return 0;
//}


//打印整数二进制的奇数位和偶数位
//int main()
//{
//	int n = 0;
//	int i = 0;
//	scanf("%d", &n);
//	//奇数位
//	for (i = 30; i >= 0; i -= 2)
//	{
//		printf("%d ", (n >> i) & 1);
//	}
//	printf("\n");
//	//偶数位
//	for (i = 31; i > 0; i -= 2)
//		printf("%d ", (n >> i) & 1);
//	return 0;
//}
//





//0001 0110  --  22
//0010 0001  --  33
//0001 1000  --24

int main()
{
	int m, n;
	while (1)
	{
		scanf("%d%d", &m, &n);
		int i = 0;
		int count = 0;
		//for (i=0; i < 32; i++)
		//{
		//	//1.
		//	/*if ((m & 1) != (n & 1))
		//		count++;
		//	m >>= 1;
		//	n >>= 1;*/

		//	//2.
		//	if (((m >> i) & 1) != ((n >> i) & 1))
		//		count++;
		//}

		//3.
		int r = m ^ n;//相同位为0，不同位为1，即求r有多少个1
		while (r)
		{
			r = r & (r - 1);
			count++;
		}
		printf("%d", count);
	}
	return 0;
}



//#include <stdio.h>
//#include<math.h>
//
//int Lily_Number(int n)
//{
//    int i, j;
//    int num = 0;
//    int g;
//    for (g = 1; g <= 4; g++)
//    {
//        int k = pow(10, g);
//        i = n % k;
//        j = n / k;
//        num += i * j;
//    }
//    if (num == n)
//    {
//        return 1;
//    }
//    return 0;
//}
//
//int main() {
//    int n = 0;
//    for (n = 10000; n <= 99999; n++)
//    {
//        if (Lily_Number(n) == 1)
//        {
//            printf("%d ", n);
//        }
//    }
//    return 0;
//}